// Copyright 2008 David Mitchell
// Released under the MIT License

using System;
using System.ComponentModel;

namespace NSDuctTape
{
	public abstract class NotifyPropertyChangingBase : INotifyPropertyChanging, INotifyPropertyChanged
	{
		public event PropertyChangedEventHandler PropertyChanged;
		public event PropertyChangingEventHandler PropertyChanging;

		public IDisposable ChangeProperties(params string[] properties)
		{
			return new PropertyChangingScope(this, properties);
		}

		private void NotifyPropertyChanging(params string[] properties)
		{
			NSDuctTape.PropertyChangingEventHandler handler = PropertyChanging;
			if (handler != null)
			{
				foreach (string property in properties)
					handler(this, new NSDuctTape.PropertyChangingEventArgs(property));
			}
		}

		private void NotifyPropertyChanged(params string[] properties)
		{
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null)
			{
				for (int property = properties.Length - 1; property >= 0; property--)
					handler(this, new PropertyChangedEventArgs(properties[property]));
			}
		}

		private class PropertyChangingScope : IDisposable
		{
			public PropertyChangingScope(NotifyPropertyChangingBase parent, string[] properties)
			{
				_parent = parent;
				_properties = properties;

				_parent.NotifyPropertyChanging(_properties);
			}

			public void Dispose()
			{
				if (!_isDisposed)
					_parent.NotifyPropertyChanged(_properties);

				_isDisposed = true;
			}

			bool _isDisposed;
			readonly string[] _properties;
			readonly NotifyPropertyChangingBase _parent;
		}
	}
}
